package com.learn.egcar1.base.exception;

import com.learn.egcar1.base.response.JsonResult;
import com.learn.egcar1.base.response.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;

/*
* ControllerAdvice注解：标识该类为Spring MVC全局异常处理类；
*   1. 当Controller中抛出异常时，框架检查是否定义了全局异常处理器；
*   2. 如果有，则在该类中查找是否定义了对应的异常处理方法；
*   3. 如果有，则由该方法处理异常，并返回响应给到客户端；
* */
//@ControllerAdvice
@Slf4j
@RestControllerAdvice//包含了RespenseBody注解
public class GlobalExceptionHandler {

    /*
    * 第1个异常处理方法，处理IllegalArgumentException异常
    * */
    @ExceptionHandler
    public JsonResult doHandleIllegalArgumentException(IllegalArgumentException e){
        String message = e.getMessage();//获取controller中那个"id不能小于0"

        log.error("IllegalArgumentException:{}", message);

        return new JsonResult(StatusCode.OPERATION_FAILED,message);
    }

    //第2个异常处理方法，pojo类的校验异常[validation校验]
    @ExceptionHandler
    public JsonResult doHandleMethodArgumentNotValidException(MethodArgumentNotValidException ex){
        /*
        *  1.pojo参数校验失败，使用：String data = ex.getFieldError().getDefaultMessage()获取异常提示消息
        * */
        String data = ex.getFieldError().getDefaultMessage();
        log.error("MethodArgumentNotValidException:{}", data);
        return new JsonResult(StatusCode.OPERATION_FAILED,data);
    }

    //第3个异常处理方法，声明参数校验[Validation]
    @ExceptionHandler
    public JsonResult doHandleConstraintViolationException(ConstraintViolationException ex){
        /*
        * deleteVehicle.id: 车辆id必须在1到100之间     通过.split(":")[1].trim()    切割出来中文
        * */
        String data = ex.getMessage().split(":")[1].trim();
        log.error("ConstraintViolationException:{}", data);
        return new JsonResult(StatusCode.OPERATION_FAILED,data);
    }

    /*
     * 第4个异常处理方法，处理RuntimeException异常
     * */
    @ExceptionHandler
    public JsonResult doHandleRuntimeException(RuntimeException e){
        String message = e.getMessage();//获取controller中那个"id不能小于0"

        log.error("RuntimeException:{}", message);

        return new JsonResult(StatusCode.OPERATION_FAILED,message);
    }

    /*
    * 第5个异常处理方法，处理Throwable异常
    * 该方法一般时最后加
    * */
    @ExceptionHandler
    public JsonResult doHandleThrowable(Throwable ex){
        String data = ex.getMessage();
        log.error("Throwable:{}", data);
        return new JsonResult(StatusCode.THROWABLE_ERROR,data);
    }
}
